package com.soonoh.simplecube.cube;

import java.util.Random;

public class CubeRotation {
	
	public static final int AXIS_X = 0;
	public static final int AXIS_Y = 1;
	public static final int AXIS_Z = 2;

	public static final int ROTATION_CLOCKWISE = -1;
	/** opengl default */
	public static final int ROTATION_ANTICLOCKWISE = 1;
	public static final int ROTATION_OPPOSITE = 2;

	    int axis;
	    int column;
	    int direction;
	    /** there is two way to rotate interfaces, first is using mouse other press key
	     * which is represented by the faces of view(eye) point
	     * if eye point based rotation needs to convert axis of rotation and other information.
	     * therefore we need what kind of this operation.
	     * */
	    boolean isRotateBasedOnEyePoint;


	    CubeRotation() {
	        this( AXIS_X, 0, ROTATION_CLOCKWISE );
	    }

	    public CubeRotation( char rotateChar, boolean isReverse ) {
	        int reverse = 1;
	        if( isReverse ) {
	            reverse = -1;
	        }
	        switch( rotateChar ) {
	            case 'r': setRotateOperation( AXIS_X, BigCube.BIG_CUBE_LAST_INDEX, reverse * -1 ); break;
	            case 'R': setRotateOperation( AXIS_X, BigCube.BIG_CUBE_LAST_INDEX, reverse * 1 ); break;
	            case 'l': setRotateOperation( AXIS_X, 0, reverse * 1 ); break;
	            case 'L': setRotateOperation( AXIS_X, 0, reverse * -1 ); break;
	            case 'u': setRotateOperation( AXIS_Y, BigCube.BIG_CUBE_LAST_INDEX, reverse * -1 ); break;
				case 'U': setRotateOperation( AXIS_Y, BigCube.BIG_CUBE_LAST_INDEX, reverse * 1 ); break;
				case 'd': setRotateOperation( AXIS_Y, 0, reverse * 1 ); break;
				case 'D': setRotateOperation( AXIS_Y, 0, reverse * -1 ); break;
				case 'f': setRotateOperation( AXIS_Z, BigCube.BIG_CUBE_LAST_INDEX, reverse * -1 ); break;
				case 'F': setRotateOperation( AXIS_Z, BigCube.BIG_CUBE_LAST_INDEX, reverse * 1 ); break;
				case 'b': setRotateOperation( AXIS_Z, 0, reverse * 1 ); break;
				case 'B': setRotateOperation( AXIS_Z, 0, reverse * -1 ); break;
				default :
				break;
			}
			isRotateBasedOnEyePoint = true;
		}

	    public CubeRotation( int axisInt, int column, int directionInt ){
			setRotateOperation( axisInt, column, directionInt);
			isRotateBasedOnEyePoint = false;
		}

	    public boolean IsRotateBasedOnEyePoint() {
			return isRotateBasedOnEyePoint;
		}

	    public void setRotateOperation( int axisInt, int column, int directionInt ) {
			this.axis = axisInt;
			this.column = column;
			this.direction = directionInt;

		}

		public int getAxis() {
			return axis;
		}

		public int getColumn() {
			return column;
		}

		public int getColumnReverse() {
			return BigCube.BIG_CUBE_LAST_INDEX - column;
		}

		public int getDirection() {
			return direction;
		}

		@Override
		public String toString() {
			StringBuffer sb = new StringBuffer();
			sb.append("CubeRotation: axis=").append(axis);
			sb.append(", column=").append(column);
			sb.append(", direction=").append(direction);
			return sb.toString();
		}

		static Random rand;

		public static void initRandom() {
			rand = new Random();
		}

		/**
		 * get random rotation.
		 */
		public static CubeRotation random() {
			int i = rand.nextInt(3);
			CubeRotation cubeRotateOperation = new CubeRotation();
			cubeRotateOperation.axis = i;
			cubeRotateOperation.column = rand.nextInt(BigCube.SIZE);
			cubeRotateOperation.direction = (rand.nextInt(2) == 0) ? ROTATION_CLOCKWISE : ROTATION_ANTICLOCKWISE;
			return cubeRotateOperation;
		}
}
